#pragma once

#include <google/protobuf/service.h>
#include <memory>
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/TcpConnection.h>
#include <functional>
#include <google/protobuf/descriptor.h>
#include <unordered_map>

/**
 * 框架提供的专门发布 rpc 服务的网络对象类
*/
class RpcProvider
{
public:
    // 这里是框架提供给外部使用的，可以发布 rpc 方法的函数接口
    void NotifyService(google::protobuf::Service *service);

    // 启动 rpc 服务节点，开始提供 rpc 远程调用
    void Run();

private:
    // 组合 EventLoop
    muduo::net::EventLoop m_eventLoop;

    // 服务类型信息
    struct ServiceInfo
    {
        google::protobuf::Service *m_service;  // 保存服务方法
        std::unordered_map<std::string, const google::protobuf::MethodDescriptor*> m_methodMap;  // <服务方法名字，服务方法对象的描述>
    };
    std::unordered_map<std::string, ServiceInfo> m_serviceMap;  // 存储注册成功的服务对象和其服务方法的所有信息
    
    // 新的socket连接回调
    void OnConnection(const muduo::net::TcpConnectionPtr& conn);
    // 已建立连接用户的读写事件回调
    void OnMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp time);
    // Closure 回调操作，用于序列号 rpc 的响应和网络发送
    void SendRpcResponse(const muduo::net::TcpConnectionPtr& conn, google::protobuf::Message* response);
};